package com.hxht.cmp.shiro;

import com.hxht.cmp.common.Constants;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.PasswordMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.springframework.beans.factory.annotation.Value;

import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

public class RetryLimitHashedCredentialsMatcher extends PasswordMatcher {

    private Cache<String, AtomicInteger> passwordRetryCache;

    public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) {
        passwordRetryCache = cacheManager.getCache("passwordRetryCache");
    }

    @Override
    public boolean doCredentialsMatch(AuthenticationToken token,
                                      AuthenticationInfo info) {
        //记录登录次数，超过上限则抛异常
        String username = (String) token.getPrincipal();
        // retry count + 1
        AtomicInteger retryCount = passwordRetryCache.get(username);
        if (retryCount == null) {
            retryCount = new AtomicInteger(0);
            passwordRetryCache.put(username, retryCount);
        }
        if (Constants.LOGIN_NUM!=0&&retryCount.incrementAndGet() > Constants.LOGIN_NUM) {
            // if retry count > login throw
            throw new ExcessiveAttemptsException();
        }

        //取登录用户和密码比较，两个都一样则登录成功，并移除错误次数信息。
        UsernamePasswordToken tokennew = (UsernamePasswordToken) token;
        String password = new String(tokennew.getPassword());
        String principals = (String) info.getPrincipals().asList().get(0);
        String credentials = (String) info.getCredentials();
        if (Objects.equals(username, principals) && Objects.equals(password, credentials)) {
            passwordRetryCache.remove(username);
            return true;
        } else {
            throw new IncorrectCredentialsException();
        }
    }

}
